home *** CD-ROM | disk | FTP | other *** search
/ Programming Languages Suite / ProgramD2.iso / Borland / Borland Pascal with Objects 7.0 / TVDEMO.ZIP / PUZZLE.PAS < prev    next >
Pascal/Delphi Source File  |  1992-10-27  |  7KB  |  303 lines

  1. {************************************************}
  2. {                                                }
  3. {   Turbo Vision Demo                            }
  4. {   Copyright (c) 1990 by Borland International  }
  5. {                                                }
  6. {************************************************}
  7.  
  8. unit Puzzle;
  9.  
  10. {$F+,O+,S-,D-}
  11.  
  12. { Simple puzzle object. See TVDEMO.PAS for an example
  13.   program that uses this unit.
  14. }
  15.  
  16.  
  17. interface
  18.  
  19. uses views, Drivers, Objects, Crt;
  20.  
  21. const
  22.   CPuzzleView = #6#7;
  23.  
  24. type
  25.  
  26.  TBoard = array[0..5,0..5] of Char;
  27.  PPuzzleView = ^TPuzzleView;
  28.  TPuzzleView = object(TView)
  29.    Board: TBoard;
  30.    Moves: Word;
  31.    Solved: Boolean;
  32.    constructor Init(Bounds: TRect);
  33.    constructor Load(var S: TStream);
  34.    procedure HandleEvent(var Event: TEvent); Virtual;
  35.    procedure Draw; Virtual;
  36.    function  GetPalette: PPalette; virtual;
  37.    procedure MoveKey(Key: Word);
  38.    procedure MoveTile(Point: TPoint);
  39.    procedure Scramble;
  40.    procedure Store(var S: TStream);
  41.    procedure WinCheck;
  42.  end;
  43.  
  44.  PPuzzleWindow = ^TPuzzleWindow;
  45.  TPuzzleWindow = object(TWindow)
  46.    constructor Init;
  47.  end;
  48.  
  49. const
  50.   RPuzzleView: TStreamRec = (
  51.      ObjType: 10010;
  52.      VmtLink: Ofs(TypeOf(TPuzzleView)^);
  53.      Load:    @TPuzzleView.Load;
  54.      Store:   @TPuzzleView.Store
  55.   );
  56.  
  57. const
  58.   RPuzzleWindow: TStreamRec = (
  59.      ObjType: 10011;
  60.      VmtLink: Ofs(TypeOf(TPuzzleWindow)^);
  61.      Load:    @TPuzzleWindow.Load;
  62.      Store:   @TPuzzleWindow.Store
  63.   );
  64.  
  65. procedure RegisterPuzzle;
  66.  
  67. implementation
  68.  
  69. { TPuzzleWindow }
  70.  
  71. constructor TPuzzleWindow.Init;
  72. var
  73.   R: TRect;
  74. begin
  75.   R.Assign(1, 1, 21, 7);
  76.   inherited Init(R, 'Puzzle', 0);
  77.   Flags := Flags and not (wfZoom + wfGrow);
  78.   GrowMode := 0;
  79.   GetExtent(R);
  80.   R.Grow(-1, -1);
  81.   Insert(New(PPuzzleView, Init(R)));
  82. end;
  83.  
  84. { TPuzzleView }
  85.  
  86. constructor TPuzzleView.Init(Bounds: TRect);
  87. type
  88.   TBoardValue = array[1..16] of Char;
  89. const
  90.   SBoardValue: TBoardValue =
  91.     ('A','B','C','D',
  92.      'E','F','G','H',
  93.      'I','J','K','L',
  94.      'M','N','O',' ');
  95. var
  96.   I, J: Integer;
  97. begin
  98.   inherited Init(Bounds);
  99.   Randomize;
  100.   Options := Options or ofSelectable;
  101.   FillChar(Board, SizeOf(Board), '?');
  102.   for I := 0 to 3 do
  103.     for J := 0 to 3 do
  104.       Board[I+1, J+1] := SBoardValue[I*4 + J+1];
  105.   Scramble;
  106. end;
  107.  
  108. constructor TPuzzleView.Load(var S: TStream);
  109. begin
  110.   inherited Load(S);
  111.   S.Read(Board, SizeOf(Board) + Sizeof(Moves) + SizeOf(Solved));
  112. end;
  113.  
  114. Procedure TPuzzleView.Draw;
  115. var
  116.   I, J, K: Integer;
  117.   B: array[0..17] of word;
  118.   S1: String[3];
  119.   Color: array[0..1] of byte;
  120.   ColorBack: Byte;
  121. const
  122.   Map: array['A'..'O'] of Byte =
  123.     (0, 1, 0, 1,
  124.      1, 0, 1, 0,
  125.      0, 1, 0, 1,
  126.      1, 0, 1);
  127. begin
  128.   Color[0] := GetColor(1);
  129.   Color[1] := GetColor(2);
  130.   ColorBack := GetColor(1);
  131.   if Solved then Color[1] := Color[0]
  132.   else Color[1] := GetColor(2);
  133.   for I := 1 to 4 do
  134.   begin
  135.     MoveChar(B, ' ', ColorBack, 18);
  136.     if I = 2 then MoveStr(B[13], 'Move', ColorBack);
  137.     if I = 3 Then
  138.     begin
  139.       Str(Moves: 3, S1);
  140.       MoveStr(B[14], S1, ColorBack);
  141.     end;
  142.     for J := 1 to 4 do
  143.     begin
  144.       S1 := ' ' + Board[I, J] + ' ';
  145.       K := (Byte(Board[I, J]) mod 2) +1;
  146.       if Board[I, J] = ' ' then MoveStr(B[(J - 1) * 3], S1, Color[0])
  147.       else
  148.         MoveStr(B[(J - 1) * 3], S1, Color[Map[Board[I, J]]]);
  149.     end;
  150.     WriteLine(0, I - 1, 18, 1, B);
  151.   end;
  152. end;
  153.  
  154. function TPuzzleView.GetPalette: PPalette;
  155. const
  156.   P: String[Length(CPuzzleView)] = CPuzzleView;
  157. begin
  158.   GetPalette := @P;
  159. end;
  160.  
  161. procedure TPuzzleView.HandleEvent(var Event: TEvent);
  162. begin
  163.   inherited HandleEvent(Event);
  164.   if Solved and (Event.What and (evKeyDown + evMouseDown) <> 0) then
  165.   begin
  166.     Scramble;
  167.     ClearEvent(Event);
  168.   end;
  169.   case Event.What of
  170.     evMouseDown: MoveTile(Event.Where);
  171.     evKeyDown: MoveKey(Event.KeyCode);
  172.   else
  173.     Exit;
  174.   end;
  175.   ClearEvent(Event);
  176.   WinCheck;
  177. end;
  178.  
  179. procedure TPuzzleView.MoveKey(Key: Word);
  180. var
  181.   X, Y, I, J: Integer;
  182. begin
  183.   for I:=1 To 4 do
  184.     for J:=1 To 4 do
  185.       if Board[i,j] = ' ' then
  186.       begin
  187.         Y:=I;
  188.         X:=J;
  189.       end;
  190.  
  191.   case Key of
  192.     kbDown:
  193.       if Y > 1 then
  194.       begin
  195.         Board[Y, X] := Board[Y-1, X];
  196.         Board[Y-1, X] := ' ';
  197.         Inc(moves, Byte(moves<1000));
  198.       end;
  199.     kbUp:
  200.       if Y < 4 then
  201.       begin
  202.         Board[Y, X] := Board[Y+1, X];
  203.         Board[Y+1, X] := ' ';
  204.         Inc(moves, Byte(moves<1000));
  205.       end;
  206.     kbRight:
  207.       if X > 1 then
  208.       begin
  209.         Board[Y, X] := Board[Y, X-1];
  210.         Board[Y, X-1] := ' ';
  211.         Inc(moves, Byte(moves<1000));
  212.       end;
  213.     kbLeft:
  214.       if X < 4 then
  215.       begin
  216.         Board[Y, X] := Board[Y, X+1];
  217.         Board[Y, X+1] := ' ';
  218.         Inc(moves,Byte(moves<1000));
  219.       end;
  220.   end;
  221.   DrawView;
  222. end;
  223.  
  224. procedure TPuzzleView.MoveTile(Point: TPoint);
  225. var
  226.   P: TPoint;
  227.   X, Y: Word;
  228. begin
  229.   MakeLocal(Point, P);
  230.   X := ((P.X + 3) div 3);
  231.   Y := P.Y + 1;
  232.   if (X > 0) and (X < 5) and (Y > 0) and (Y < 5) Then
  233.   begin
  234.     if Board[Y, X-1] = ' ' then
  235.     begin
  236.       Board[Y, X-1] := Board[Y, X];
  237.       Board[Y, X] := ' ';
  238.       Inc(moves, Byte(moves<1000));
  239.     end;
  240.     if Board[Y-1, X] = ' ' then
  241.     begin
  242.       Board[Y-1, X] := Board[Y, X];
  243.       Board[Y, X] := ' ';
  244.       Inc(moves, Byte(moves<1000));
  245.     end;
  246.     if Board[Y, X+1] = ' ' then
  247.     begin
  248.       Board[Y, X+1] := Board[Y, X];
  249.       Board[Y, X] := ' ';
  250.       Inc(moves, Byte(moves<1000));
  251.     end;
  252.     if Board[Y+1, X] = ' ' then
  253.     begin
  254.       Board[Y+1, X] := Board[Y, X];
  255.       Board[Y, X] := ' ';
  256.       Inc(moves, Byte(moves<1000));
  257.     end;
  258.     DrawView;
  259.   end;
  260. end;
  261.  
  262. procedure TPuzzleView.Scramble;
  263. begin
  264.   Moves := 0;
  265.   Solved := False;
  266.   repeat
  267.     case Random(4) of
  268.       0: MoveKey(kbUp);
  269.       1: MoveKey(kbDown);
  270.       2: MoveKey(kbRight);
  271.       3: MoveKey(kbLeft);
  272.     end;
  273.   until Moves=500;
  274.   Moves := 0;
  275.   DrawView;
  276. end;
  277.  
  278. procedure TPuzzleView.Store(var S: TStream);
  279. begin
  280.   inherited Store(S);
  281.   S.Write(Board, SizeOf(Board) + Sizeof(Moves) + SizeOf(Solved));
  282. end;
  283.  
  284. procedure TPuzzleView.WinCheck;
  285. type
  286.   BoardStr = array [0..35] of Char;
  287. const
  288.   FBoard: BoardStr = '???????ABCD??EFGH??IJKL??MNO ???????';
  289. var
  290.   I: Integer;
  291. begin
  292.   Solved := BoardStr(Board) = FBoard;
  293.   DrawView;
  294. end;
  295.  
  296. procedure RegisterPuzzle;
  297. begin
  298.   RegisterType(RPuzzleView);
  299.   RegisterType(RPuzzleWindow);
  300. end;
  301.  
  302. end.
  303.